package org.duang.db.mongo.parser.decode;

import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.duang.kit.DataType;
import org.duang.kit.ToolsKit;

import com.mongodb.DBObject;

public class PropertyDecoder extends Decoder {

	public PropertyDecoder(DBObject dbo, Field field) {
		super(dbo, field);
	}

	@Override
	public String getFieldName() {
		return field.getName();
	}

	@Override
	public Object getFieldValue() {
		return value;
	}

	@Override
	public boolean isNullField() {
		return null == value;
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public void setObj(Object obj) {
		Class<?> fieldType = field.getType();
		try{
			if(fieldType.isArray()){
				if(isNullField()) return; //如果为null或空字符串,直接退出	
				decodeArray(obj, (ArrayList)value, fieldType.getComponentType());
			} else{
				decodeProperty(obj, fieldType);
			}
		}catch(Exception e){
			throw new RuntimeException("设置成员变量["+field.getName()+"]出错！", e);
		}
	}
	
	@SuppressWarnings("rawtypes")
	private void decodeArray(Object obj, ArrayList list, Class<?> type) throws Exception {
		int size = list.size();
		if (DataType.isString(type)) {
			String[] arr = new String[size];
			for (int i = 0; i < size; i++) {
				arr[i] = list.get(i).toString();
			}
			field.set(obj, arr);
		} else if (DataType.isInteger(type)) {
			int[] arr = new int[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Integer.parseInt(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isIntegerObject(type)) {
			Integer[] arr = new Integer[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Integer.parseInt(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isLong(type)) {
			long[] arr = new long[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Long.parseLong(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isLongObject(type)) {
			Long[] arr = new Long[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Long.parseLong(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isShort(type)) {
			short[] arr = new short[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Short.parseShort(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isShortObject(type)) {
			Short[] arr = new Short[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Short.parseShort(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isFloat(type)) {
			float[] arr = new float[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Float.parseFloat(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isFloatObject(type)) {
			Float[] arr = new Float[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Float.parseFloat(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isDouble(type)) {
			double[] arr = new double[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Double.parseDouble(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isDoubleObject(type)) {
			Double[] arr = new Double[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Double.parseDouble(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isBoolean(type)) {
			boolean[] arr = new boolean[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Boolean.parseBoolean(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isBooleanObject(type)) {
			Boolean[] arr = new Boolean[size];
			for (int i = 0; i < size; i++) {
				arr[i] = Boolean.parseBoolean(list.get(i).toString());
			}
			field.set(obj, arr);
		} else if (DataType.isChar(type)) {
			char[] arr = new char[size];
			for (int i = 0; i < size; i++) {
				arr[i] = list.get(i).toString().charAt(0);
			}
			field.set(obj, arr);
		} else if (DataType.isCharObject(type)) {
			Character[] arr = new Character[size];
			for (int i = 0; i < size; i++) {
				arr[i] = list.get(i).toString().charAt(0);
			}
			field.set(obj, arr);
		} else if (DataType.isDate(type)) {
			Date[] arr = new Date[size];
			for (int i = 0; i < size; i++) {
				arr[i] = (Date) list.get(i);
			}
			field.set(obj, arr);
		} else if (DataType.isTimestamp(type)) {
			Timestamp[] arr = new Timestamp[size];
			for (int i = 0; i < size; i++) {
				arr[i] = (Timestamp) list.get(i);
			}
			field.set(obj, arr);
		}
	}
	
	private void decodeProperty(Object obj, Class<?> type) throws Exception{
		Object fieldValue = getFieldValue(); 
		if( null ==fieldValue) return;		//如果为null,直接退出		
		field.setAccessible(true);
		if (DataType.isString(type)) {			
			field.set(obj, fieldValue.toString());			
		} else if (DataType.isInteger(type)) {
			String tmpValue = fieldValue.toString();
			int index = tmpValue.indexOf(".");
			if(index > -1){ tmpValue= fieldValue.toString().substring(0,index);} 
			field.set(obj, Integer.parseInt(tmpValue));
		} else if (DataType.isIntegerObject(type)) {
			String tmpValue = fieldValue.toString();
			int index = tmpValue.indexOf(".");
			if(index > -1){ tmpValue= fieldValue.toString().substring(0,index);} 
			field.set(obj, Integer.valueOf(tmpValue));
		} else if (DataType.isDouble(type)) {
			field.set(obj, Double.parseDouble(fieldValue.toString()));
		} else if (DataType.isDoubleObject(type)) {
			field.set(obj, Double.valueOf(fieldValue.toString()));
		} else if (DataType.isFloat(type)) {
			field.setFloat(obj, Float.parseFloat(fieldValue.toString()));
		} else if (DataType.isFloatObject(type)) {
			field.set(obj, Float.valueOf(fieldValue.toString()));
		} else if (DataType.isShort(type)) {
			field.setShort(obj, Short.parseShort(fieldValue.toString()));
		} else if (DataType.isShortObject(type)) {
			field.set(obj, Short.valueOf(fieldValue.toString()));
		} else if (DataType.isBoolean(type)) {
			field.set(obj, Boolean.parseBoolean(fieldValue.toString()));
		} else if (DataType.isBooleanObject(type)) {
			field.set(obj, Boolean.valueOf(fieldValue.toString()));
		} else if (DataType.isChar(type)) {
			field.set(obj, fieldValue.toString().charAt(0));
		} else if (DataType.isCharObject(type)) {
			field.set(obj, fieldValue.toString().charAt(0));
		} else if (DataType.isListType(type)) {
			List list = (ArrayList) value;
			field.set(obj, list);
		} else if (DataType.isSetType(type)) {
			List list = (ArrayList) value;
			field.set(obj, new HashSet(list));
		} else if (DataType.isMapType(type)) {
			Map map = (HashMap) value;
			field.set(obj, map);
		} else if (DataType.isQueueType(type)) {
			List list = (ArrayList) value;
			field.set(obj, new LinkedList(list));
		} else if (DataType.isDate(type)) {
			Date date = (Date) value;
			field.set(obj, date);
		} else if (DataType.isTimestamp(type)) {
			Date date = (Date) value;
			field.set(obj, new Timestamp(date.getTime()));
		} else {
			field.set(obj, value); // for others
		}
	}

}
